library ieee;
use ieee.std_logic_1164.all;

entity ps2_kb_aau is
  port (
    reset      : in std_logic;
    clock      : in std_logic;

    read       : in std_logic;
    readdata   : out std_logic_vector (7 downto 0);

    irq        : out std_logic;

    dev_clk    : in std_logic;
    dev_dat    : in std_logic
  );
end entity ps2_kb_aau;

architecture behavioral of ps2_kb_aau is
  type state_t is (WAIT_SCODE, REQ_INT);

  signal state_reg : state_t;
  signal state_nxt : state_t;
  
  signal scode : std_logic_vector (7 downto 0);
  signal error : std_logic;

  signal scode_rdy : std_logic;

  signal scode_reg : std_logic_vector (7 downto 0);
  signal scode_nxt : std_logic_vector (7 downto 0);
begin
  ps2_kb_inst : entity work.ps2_kb
    port map (reset, clock, dev_clk, dev_dat, scode_rdy, scode, error);

  process (reset, clock) is
  begin
    if reset = '1' then
      state_reg <= WAIT_SCODE;
    elsif rising_edge (clock) then
      state_reg <= state_nxt;
      scode_reg <= scode_nxt;
    end if;
  end process;

  process (state_reg, scode_reg, scode, scode_rdy, error, read) is
  begin
    state_nxt <= state_reg;
    scode_nxt <= scode_reg;
    readdata <= (readdata'range => 'Z');
    irq <= '0';
    case state_reg is
      when WAIT_SCODE =>
        if scode_rdy = '1' and error = '0' then
          state_nxt <= REQ_INT;
          scode_nxt <= scode;
        end if;
      when REQ_INT =>
        irq <= '1';
        if read = '1' then
          state_nxt <= WAIT_SCODE;
          readdata <= scode_reg;
        end if;
    end case;
  end process;
end architecture behavioral;
